#ifndef HTTPRESPONSE_H
#define HTTPRESPONSE_H
#include <string>
#include <map>
#include <assert.h>
#include "sha1.hpp"
#include "base64.hpp"


#include "Buffer.hpp"

enum class HttpStatusCode{
    None,
    OK = 200,
    SwitchingProtocols = 101,
    PartialContent=206,
    NotFound = 404,
    Forbidden = 403,
    MethodNotAllowed = 405,
    InternalServerError = 500,
    GatewayTimeout = 504,
    MoveTemporarily = 302,
    MovedPermanently = 301
};

extern std::map<HttpStatusCode, std::string> statusCommentMap;

class HttpResponse {
public:
    HttpResponse()=default;
    ~HttpResponse()=default;
    inline void setVersion(const std::string& version){
        assert(version == "HTTP/1.1" && version == "HTTP/1.0" && version == "HTTP/2.0");
        version_ = version;
    }

    inline void setStatus(HttpStatusCode status) {
        status_ = status;
        statusComment_ = statusCommentMap[status_];
    }

    inline void setContentType(const std::string& type) {
        addHeader("Content-Type", type);
    } 
    
    void reset(){
        version_ = "HTTP/1.1";
        status_=HttpStatusCode::None; 
        statusComment_.clear();
        respHeaders_.clear();
        content_ = nullptr;
        contentSize_ = 0;
    }

    void addHeader(const std::string& key, const std::string& value);
    std::string getHeader(const std::string& key);


    int writeBuffer(Buffer* outBuffer);
    void addFile(std::string filePath);
    void addContent(const char* content, int size);

    void setWebSocketResponse(std::string key){
        setStatus(HttpStatusCode::SwitchingProtocols);
        addHeader("Upgrade", "websocket");
        addHeader("Connection", "Upgrade");

        
        key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
        SHA1 sha;
        unsigned int message_digest[5];
        sha.Reset();
        sha << key.c_str();

        sha.Result(message_digest);
        for (int i = 0; i < 5; i++) {
            message_digest[i] = htonl(message_digest[i]);
        }
        key = base64_encode(reinterpret_cast<const unsigned char*>(message_digest),20);
        addHeader("Sec-WebSocket-Accept", key);
    }

private:
    std::string version_;
    HttpStatusCode status_=HttpStatusCode::None; 
    std::string statusComment_;
    std::map<std::string, std::string> respHeaders_;
    char* content_=nullptr;
    int contentSize_;

};

#endif